package com.dkts.oil.router.impl;

import com.dkts.oil.config.OilConfig;
import com.dkts.oil.converter.*;
import com.dkts.oil.model.GHPoint;
import com.dkts.oil.router.param.PipelineRouterInfo;
import com.dkts.oil.test.relrouter.AstartTest;
import com.dkts.oil.test.road.PolygonCutter;
import com.dkts.oil.util.GeoGridUtil;
import com.dkts.oil.web.vo.request.PipelineRouteRequest;
import com.graphhopper.GraphHopper;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class PipelineRouterInfoImpl {
    @Autowired
    OilAddressV2Converter oilAddressV2Converter;

    @Autowired
    private OilConfig oilConfig;

    /**
     * 库区内部关系规划
     *
     * @param request
     * @return
     */
    public List<PipelineRouterInfo> pipelineRouter(PipelineRouteRequest request) throws Exception {
        List<PipelineRouterInfo> list = new ArrayList<>();

        List<PipelineRouteRequest.LineRouterPont> listPoint = request.getPoints();
        for (int i = 0; i < listPoint.size(); i++) {
            PipelineRouteRequest.LineRouterPont lineRouterPont = listPoint.get(i);

            List<GHPoint> ghPoints = lineRouterPont.getPoints();
            Coordinate[] coordinates = convertToCoordinates(ghPoints);
            LineString lineString = GeometryConverter.locationtechGeometryFactory.createLineString(coordinates);

            // 获取路径的缓冲区域
            Geometry polygonBuff = GeometryConverter.getBuff(lineString, request.diameter);
            List<Geometry> listObstacles = oilAddressV2Converter.routeObstacles(polygonBuff, request, true);

            // 繁重的路径绕障处理
            List<Coordinate> temp = PolygonCutter.routerGeometry(listObstacles, lineString);

            // 生成绕过障碍物的路径
            List<Coordinate> newPath = buildNewPath(ghPoints, temp);

            // 转换为LineString并保存为GeoJSON
            LineString finalLineString = createFinalLineString(newPath);
            WriterToFile.writerFileGeoJsonLine(oilConfig.getTempDir() + "/" + lineRouterPont.getName() + ".geojson", finalLineString);

            // 构建路径信息
            PipelineRouterInfo pipelineRouterInfo = buildPipelineRouterInfo(lineRouterPont, newPath, finalLineString);
            list.add(pipelineRouterInfo);
        }
        return list;
    }

    // 坐标转换方法
    private Coordinate[] convertToCoordinates(List<GHPoint> ghPoints) {
        Coordinate[] coordinates = new Coordinate[ghPoints.size()];
        for (int i = 0; i < ghPoints.size(); i++) {
            GHPoint ghPoint = ghPoints.get(i);
            coordinates[i] = new Coordinate(ghPoint.getLon(), ghPoint.getLat());
        }
        return coordinates;
    }

    // 生成绕障后的路径
    private List<Coordinate> buildNewPath(List<GHPoint> ghPoints, List<Coordinate> bypassPoints) {
        List<Coordinate> newPath = new ArrayList<>();
        newPath.add(new Coordinate(ghPoints.get(0).getLon(), ghPoints.get(0).getLat())); // 添加起点
        if (bypassPoints != null) {
            newPath.addAll(bypassPoints);
        }
        newPath.add(new Coordinate(ghPoints.get(ghPoints.size() - 1).getLon(), ghPoints.get(ghPoints.size() - 1).getLat())); // 添加终点
        return newPath;
    }

    // 创建最终的LineString对象
    private LineString createFinalLineString(List<Coordinate> newPath) {
        Coordinate[] finalCoordinates = new Coordinate[newPath.size()];
        newPath.toArray(finalCoordinates);
        return GeometryConverter.locationtechGeometryFactory.createLineString(finalCoordinates);
    }

    // 构建路径信息
    private PipelineRouterInfo buildPipelineRouterInfo(PipelineRouteRequest.LineRouterPont lineRouterPont, List<Coordinate> newPath, LineString finalLineString) {
        PipelineRouterInfo pipelineRouterInfo = new PipelineRouterInfo();
        pipelineRouterInfo.setName(lineRouterPont.getName());

        PipelineRouterInfo.PathLineInfo paths = new PipelineRouterInfo.PathLineInfo();
        paths.setDistance(finalLineString.getLength() * 100000); // 转换为米
        paths.setRoadInfos(new PipelineRouterInfo.RouteLinePoints(newPath));

        pipelineRouterInfo.setPaths(paths);
        return pipelineRouterInfo;
    }

}
